from QQLoginTool.QQtool import OAuthQQ
from django import http
from django.conf import settings
from django.contrib.auth import login
from django.shortcuts import render, redirect
# Create your views here.
from django.urls import reverse
from django.views import View
import logging
import re

from django_redis import get_redis_connection
from pymysql import DatabaseError
from requests import request

from carts.utils import merge_cart_cookie_to_redis
from meiduo_mall.utils.response_code import RETCODE
from oauth.models import OauthQQUser
from users.models import User
from oauth.utils import generate_access_token,check_access_token

logger = logging.getLogger('django')


class QQAuthUrlView(View):
    """用户扫码登录的回调处理"""
    def get(self,request):


        next = request.GET.get('next')
        # 获取QQ登录页面网址
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=next)
        login_url = oauth.get_qq_url()

        # 响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url':login_url})

class QQAuthUserView(View):
    '''处理qq登录回调oauth_callback'''
    def get(self,request):
        '''获取code'''
        code = request.GET.get('code')
        if not code:
            return http.HttpResponseForbidden('获取code失败')
        # 创建工具对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            '''使用code获取access_token'''
            access_token = oauth.get_access_token(code)
            '''使用access_token获取openid'''
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseForbidden('oauth2.0认证失败')
        '''通过openid来验证用户是否绑定'''

        try:
            oauth_user = OauthQQUser.objects.get(openid = openid)
        except OauthQQUser.DoesNotExist:
            '''吧openid渲染到前端'''
            access_token_openid = generate_access_token(openid)
            context = {'access_token_openid':access_token_openid}
            '''如果没有绑定没多用户(返回一个绑定页面'''
            return render(request,'oauth_callback.html',context)
        else:
            '''如果绑定了没多用户,oauth_user.user表示从qq登录的模型类中找到对应的模型类对象'''
            login(request,oauth_user.user)
            response =  redirect(reverse('contents:index'))
            '''将用户名写入到cookie中'''
            response.set_cookie('username', oauth_user.user.username, max_age=60 * 60 * 24 * 15)

            '''响应qq登录的结果（重定向到首页'''
            return response
    '''实现绑定'''
    '''接受参数'''
    def post(self,request):
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        sms_code_client = request.POST.get('sms_code')
        access_token = request.POST.get('access_token')
        '''校验参数'''
        '''校验参数是否齐全'''
        if not all([mobile, password, sms_code_client]):
            return http.HttpResponseForbidden('缺少必传参数')
        '''校验电话号码格式是否正确'''
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return http.HttpResponseForbidden('请输入正确的电话号码')
        '''校验密码是否符合规则'''
        if not re.match(r'^[0-9a-zA-Z]{8,20}$',password):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        '''校验短信验证码是否一致'''
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if sms_code_server is None:
            return render(request,'oauth_callback.html',{'sms_code_errmsg':'短信验证码无效'})
        if sms_code_server != sms_code_client:
            return render(request,'oauth_callback.html',{'sms_code_errmsg':'短信验证码有误'})
        '''判断openid是否有效：错误提示放在sms_code_errmsg位置'''
        openid = check_access_token(access_token)
        if not openid:
            return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})

        # 保存注册数据
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 用户不存在,新建用户
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        else:
            # 如果用户存在，检查用户密码
            if not user.check_password(password):
                return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})

        # 将用户绑定openid
        try:
            OauthQQUser.objects.create(openid=openid, user=user)
        except DatabaseError:
            return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'})
        # 实现状态保持
        login(request, user)
        # 响应绑定结果
        next = request.GET.get('state')
        response = redirect(next)
        # 登录时用户名写入到cookie，有效期15天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)
        #合并购物车
        response = merge_cart_cookie_to_redis(request=request, user=user, response=response)
        return response




